﻿using System.IO;
using System.Xml.Linq;

namespace Red.Controls.Utils
{
    public class XmlHelper
    {
        /// <summary>
        /// Safely save XML to file
        /// </summary>
        /// <remarks>
        /// Writes to a temporary file first in case there was an error saving
        /// </remarks>
        /// <param name="root">The root node of the xml to save</param>
        /// <param name="path">The path to the file to be saved</param>
        public static void Save( XContainer root, string path )
        {
            // Write it to a temporary location first in case the save process fails
            string intermediaryLocation = path + ".tmp";
            
            // Ensure the destination directory exists
            DirectoryInfo directoryInfo = new DirectoryInfo( Path.GetDirectoryName( path ) );
            directoryInfo.Create();

            XDocument doc = new XDocument( root );
            doc.Save( intermediaryLocation );

            // Saving complete, replace the existing file (if applicable) with the new one
            if ( File.Exists( path ) )
            {
                File.Replace( intermediaryLocation, path, null );
                File.Delete( intermediaryLocation );
            }
            else
            {
                File.Move( intermediaryLocation, path );
            }
        }

        /// <summary>
        /// Add attribute to xml node
        /// </summary>
        /// <remarks>
        /// Attribute ignored if invalid parameters are specified
        /// </remarks>
        /// <returns><see langword="true"/> if attribute was successfully added to the node, otherwise <see langword="false"/></returns>
        /// <seealso cref="GetAttribute"/>
        public static bool AddAttribute( XElement node, string name, object value )
        {
            if ( !string.IsNullOrEmpty( name ) && value != null )
            {
                XAttribute attr = new XAttribute( name, value );
                node.Add( attr );

                return true;
            }

            return false;
        }

        /// <summary>
        /// Get the value of a particular attribute
        /// </summary>
        /// <returns>The value of the specified attribute as a <see langword="string"/>. <see langword="null"/> if not found</returns>
        /// <seealso cref="AddAttribute"/>
        public static string GetAttribute( XElement node, string name )
        {
            if ( !string.IsNullOrEmpty( name ) && node != null )
            {
                XAttribute attribute = node.Attribute( name );

                if ( attribute != null )
                {
                    return attribute.Value;
                }
            }

            return null;
        }
    }
}
